/*
 * CgMain.c
 *
 *  Created on: 2012/06/07
 *      Author: guanxiaoying
 */

#include "../coredef.h"
#include "../cc/cc.h"
#include "cg.h"

/*debug,12/10/09,S*/
static AST gblPreCmdMax = 0;
/*debug,12/10/09,E*/

static S4 cg_StoreLinkageData( AST astVariOffset, AST astFunctionOffset, AST astLinkOffset ){
	AST astLinkage;
	AST astMaxLinkage;
	AST astLinkStorage;
	BOOL bRet;
	AST astSym;
	AST astRelation;
	AST astVari;
	AST astPreVariMax = astVariOffset;

	astMaxLinkage = stCCLinkageAccess.getMax();
	for( astLinkage = MIN_ARRAY; astLinkage <= astMaxLinkage; astLinkage++ ){
		astSym = stCCLinkageAccess.allChain.get( astLinkage );
		astSym = stUniteChainAccess.parameter_sym.get( astSym );
		bRet = stCgSymbolRelationAccess.findMemSymbol( astSym, &astRelation );
		if( bRet == TRUE ){
			astVari = stCgSymbolRelationAccess.linkedSym.get( astRelation );

			stCCLinkageStackAccess.alloc(1);
			astLinkStorage = stCCLinkageStackAccess.getMax();
			stCCLinkageStackAccess.bExternal.set( astLinkStorage,
					stCCLinkageAccess.bExternal.get( astLinkage ));
			stCCLinkageStackAccess.refer.set( astLinkStorage,
					stCCLinkageAccess.bReferred.get( astLinkage ));
			if( stSymbolInfoAccess.kind.get(astSym) == SYMBOL_KIND_FUNCTION ){
				astVari +=astFunctionOffset;
				stCCLinkageStackAccess.bFunction.set( astLinkStorage, TRUE  );
			}else{
				astVari +=astPreVariMax;
			}
			if( stCCLinkageAccess.definitionSym.get( astLinkage )){
				stCCLinkageStackAccess.vari.set( astLinkStorage, astVari );
			}
			if( stCCLinkageAccess.tenDeclChain.get( astLinkage )){
				stCCLinkageStackAccess.tenVari.set( astLinkStorage, astVari );
			}
			stCCLinkageStackAccess.decVari.set( astLinkStorage, astVari );
		}else{
			stCCLinkageStackAccess.alloc(1);
			//typedef symbols
		}
	}

	return COEXIT_SUCCESS;
}
static S4 cg_StoreVariable( AST astVariOffset, AST astFunctionOffset, AST astLinkOffset ){
	AST astMaxVari;
	AST astVariStorage;
	AST astVari;
	AST astPreVariMax = astVariOffset;
	AST astPreCCLinkageMax = astLinkOffset;
	AST astTemp;

	astMaxVari = stVariableInfoAccess.getMax();
	for( astVari = MIN_ARRAY; astVari <= astMaxVari; astVari++ ){
		stVariableStorageAccess.alloc(1);
		astVariStorage = stVariableStorageAccess.getMax();
		stVariableStorageAccess.bSizeVariable.set( astVariStorage,
							stVariableInfoAccess.bSizeVariable.get( astVari ));
		astTemp = stVariableInfoAccess.child.get( astVari ) ;
		if( astTemp ){
			astTemp+= astPreVariMax;
		}
		stVariableStorageAccess.child.set( astVariStorage,
				astTemp );
		stVariableStorageAccess.codeScp.set( astVariStorage,
							stVariableInfoAccess.codeScp.get( astVari ) );
		stVariableStorageAccess.dataSection.set( astVariStorage,
							stVariableInfoAccess.dataSection.get( astVari ) );
		stVariableStorageAccess.initialCmdBegin.set( astVariStorage,
							stVariableInfoAccess.initialCmdBegin.get( astVari ) );
		stVariableStorageAccess.initialCmdEnd.set( astVariStorage,
							stVariableInfoAccess.initialCmdEnd.get( astVari ) );
		stVariableStorageAccess.length.set( astVariStorage,
							stVariableInfoAccess.length.get( astVari ) );
		astTemp = stVariableInfoAccess.linkage.get( astVari );
		if( astTemp ){
			astTemp += astPreCCLinkageMax;
		}
		stVariableStorageAccess.linkage.set( astVariStorage,
				astTemp );
		stVariableStorageAccess.name.set( astVariStorage,
							stVariableInfoAccess.name.get( astVari ) );
		astTemp = stVariableInfoAccess.next.get( astVari ) ;
		if( astTemp ){
			astTemp+= astPreVariMax;
		}
		stVariableStorageAccess.next.set( astVariStorage,
				astTemp );
		stVariableStorageAccess.offset.set( astVariStorage,
							stVariableInfoAccess.offset.get( astVari ));
		astTemp = stVariableInfoAccess.parent.get( astVari );
		if( astTemp ){
			astTemp+= astPreVariMax;
		}
		stVariableStorageAccess.parent.set( astVariStorage,
				astTemp );
		astTemp = stVariableInfoAccess.parent.get( astVari );
		if( astTemp ){
			astTemp+= astPreVariMax;
		}
		stVariableStorageAccess.prev.set( astVariStorage,
				astTemp );
		stVariableStorageAccess.symClass.set( astVariStorage,
							stVariableInfoAccess.symClass.get( astVari ));
		stVariableStorageAccess.type.set( astVariStorage,
							stVariableInfoAccess.type.get( astVari ));
		stVariableStorageAccess.value.set( astVariStorage,
							stVariableInfoAccess.value.get( astVari ));
	}
	stVariableInfoAccess.clear();
	return COEXIT_SUCCESS;
}
static S4 cg_StoreFunction( AST astVariOffset, AST astFunctionOffset, AST astLinkOffset ){
	AST astMaxFunction;
	AST astFunction;
	AST astFuncStorage;
	AST astTemp;

	astMaxFunction = stFunctionInfoAccess.getMax();
	for( astFunction = MIN_ARRAY; astFunction <= astMaxFunction; astFunction++ ){
		stFunctionStorageAccess.alloc(1);
		astFuncStorage = stFunctionStorageAccess.getMax();
		stFunctionStorageAccess.codeScp.set( astFuncStorage,
				stFunctionInfoAccess.codeScp.get( astFunction ));
		stFunctionStorageAccess.functionEntry.set( astFuncStorage,
				stFunctionInfoAccess.functionEntry.get( astFunction ));
		stFunctionStorageAccess.functionExit.set( astFuncStorage,
				stFunctionInfoAccess.functionExit.get( astFunction ));
		astTemp = stFunctionInfoAccess.linkage.get( astFunction );
		if( astTemp ){
			astTemp += astLinkOffset;
		}
		stFunctionStorageAccess.linkage.set( astFuncStorage,
				astTemp );
		stFunctionStorageAccess.name.set( astFuncStorage,
				stFunctionInfoAccess.name.get( astFunction ) );
		stFunctionStorageAccess.symClass.set( astFuncStorage,
				stFunctionInfoAccess.symClass.get( astFunction ) );
		stFunctionStorageAccess.type.set( astFuncStorage,
				stFunctionInfoAccess.type.get( astFunction ) );
	}
	stFunctionInfoAccess.clear();
	return COEXIT_SUCCESS;
}
static S4 cg_StoreOperand( AST astVariOffset, AST astFunctionOffset, AST astLinkOffset ){
	AST astMaxOperand;
	AST astOperand;
	AST astMng = stStorageManagerAccess.getMax();
	astMaxOperand = stOperandAccess.getMax();
	/*debug,12/10/09,S*/
	astOperand =stStorageManagerAccess.preOperand.get( astMng )+1;
	/*debug,12/10/09,E*/

	for( ; astOperand <= astMaxOperand; astOperand++ ){
		switch( stOperandAccess.kind.get( astOperand ) ){
		case OPERAND_OBJECT:
			stOperandAccess.parameter.set( astOperand,
					 stOperandAccess.parameter.get( astOperand ) + astVariOffset );
			break;
		case OPERAND_FUNCTION:
			stOperandAccess.parameter.set( astOperand,
					 stOperandAccess.parameter.get( astOperand ) + astFunctionOffset );
			break;
		}
	}
	return COEXIT_SUCCESS;
}
/*debug,12/10/09,S*/
static S4 cg_StoreCmdList( AST astPreFuncMax ){
	AST astCmd;
	AST astMaxCmdList = stCmdListAccess.getMax();
	if(astMaxCmdList == 0 || astPreFuncMax == 0){
		gblPreCmdMax = astMaxCmdList;
		return COEXIT_SUCCESS;
	}
	for(astCmd = gblPreCmdMax + 1; astCmd <= astMaxCmdList; astCmd++){
		if( stCmdListAccess.function.get(astCmd) > 0 ){
			stCmdListAccess.function.set(astCmd, stCmdListAccess.function.get(astCmd)+astPreFuncMax);
		}
	}
	gblPreCmdMax = astMaxCmdList;
	return COEXIT_SUCCESS;
}
/*debug,12/10/09,E*/
static S4 cg_StoreData( VOID ){
	AST astMng = stStorageManagerAccess.getMax();
	AST astPreVariMax = stStorageManagerAccess.preVariMax.get( astMng );
	AST astPreCCLinkageMax = stStorageManagerAccess.preLinkageMax.get( astMng );
	AST astPreFuncMax = stStorageManagerAccess.preFuncMax.get( astMng );
	cg_StoreLinkageData( astPreVariMax, astPreFuncMax, astPreCCLinkageMax );
	cg_StoreVariable( astPreVariMax, astPreFuncMax, astPreCCLinkageMax );
	cg_StoreFunction( astPreVariMax, astPreFuncMax, astPreCCLinkageMax );
	cg_StoreOperand( astPreVariMax, astPreFuncMax, astPreCCLinkageMax );
	/*debug,12/10/09,S*/
	cg_StoreCmdList(astPreFuncMax);
	/*debug,12/10/09,E*/
	stCCLinkageAccess.clear();
	return COEXIT_SUCCESS;
}
S4 DLL_EXPORT CGProcessing( AST astTu ){
	AST astDeclaration;
	AST astMng;

	stStorageManagerAccess.alloc(1);
	astMng = stStorageManagerAccess.getMax();
	stStorageManagerAccess.preFuncMax.set( astMng,  stFunctionStorageAccess.getMax() );
	stStorageManagerAccess.preVariMax.set( astMng, stVariableStorageAccess.getMax() );
	stStorageManagerAccess.preLinkageMax.set( astMng,  stCCLinkageStackAccess.getMax() );
	stStorageManagerAccess.preOperand.set(astMng, stOperandAccess.getMax());
	astDeclaration = stCoreTranslationUnitAccess.declarationchain.get( astTu );
	while( astDeclaration ){
		CG_StaticDeclaration( astDeclaration );
		astDeclaration = stDeclarationAccess.next.get( astDeclaration );
	}
	cg_StoreData();
	stCgSymbolRelationAccess.clear();
	stCgConfluxNodeStackAccess.clear();
	stFunctionNestAccess.clear();
	stPostIncDecStkAccess.clear();

	return COEXIT_SUCCESS;
}
